
#include <BTreeWidget>
#include <BTreeItem>
#include "member_BTreeItem.h"
#include "member_BTreeWidget.h"
#include "member_BObject.h"

using namespace BWE;

#define member					(*(member_BTreeItem*)_ptr)
#define member_allocate()		_ptr = new member_BTreeItem(this)
#define member_release()		delete (member_BTreeItem*)_ptr

BTreeItem::BTreeItem(BTreeItem* parent)
{
	member_allocate();
	setParent(parent);
	member.dirtyTree();
}
BTreeItem::BTreeItem(const BString& text, BTreeItem* parent)
{
	member_allocate();
	setText(text);
	setParent(parent);
	member.dirtyTree();
}
BTreeItem::BTreeItem(Graph graph, const BString& text, Form form)
{
	member_allocate();
	setGraph(graph);
	setText(text);
	setForm(form);
	member.dirtyTree();
}
BTreeItem::BTreeItem(BIcon* icon, const BString& text, Form form)
{
	member_allocate();
	setIcon(icon);
	setText(text);
	setForm(form);
	member.dirtyTree();
}
BTreeItem::BTreeItem(BImage* image, const BString& text, Form form)
{
	member_allocate();
	setImage(image);
	setText(text);
	setForm(form);
	member.dirtyTree();
}
BTreeItem::BTreeItem(BWidget* widget, const BString& text, Form form)
{
	member_allocate();
	setWidget(widget);
	setText(text);
	setForm(form);
	member.dirtyTree();
}
BTreeItem::~BTreeItem()
{
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		item_member(child)->parent = 0;
	}
	member_release();
}

bool BTreeItem::setEnabled(bool enabled)
{
	if (BObject::setEnabled(enabled))
	{
		this->fresh();
		return true;
	}
	return false;
}

void BTreeItem::setVisible(bool visible)
{
	if (member.visible != visible)
	{
		member.visible = visible;
		if (member.visible)
			this->emit(Signal_Show, true);
		else
			this->emit(Signal_Hide, false);
		member.dirtyTree();
	}
}
bool BTreeItem::visible() const
{
	return member.visible;
}

void BTreeItem::setExpanded(bool expanded)
{
	if (member.expanded != expanded)
	{
		if (member.tree)
		{
			if (expanded)
				member.tree->expand(this);
			else
				member.tree->shrink(this);
			member.dirtyTree();
		}
		else
		{
			member.expanded = expanded;
		}
	}
}
bool BTreeItem::expanded() const
{
	return member.expanded;
}

void BTreeItem::setSelected(bool selected)
{
	if (member.tree && member.selected != selected)
	{
		member.tree->setItemSelected(this, selected);
	}
}
bool BTreeItem::selected() const
{
	return member.tree && member.selected;
}

void BTreeItem::setChecked(bool checked)
{
	if (member.checked != checked)
	{
		member.checked = checked;
		emit(Signal_Checked, checked);
		this->fresh();
	}
}
bool BTreeItem::checked() const
{
	return member.checked;
}

void BTreeItem::setAlign(Align align)
{
	if (member.align != align)
	{
		member.align = align;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_AlignChanged, align);
	}
}
Align BTreeItem::align() const
{
	return member.align;
}

void BTreeItem::setForm(Form form)
{
	if (member.form != form)
	{
		member.form = form;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_FormChanged, form);
	}
}
Form BTreeItem::form() const
{
	return member.form;
}

void BTreeItem::setColor(BByte r, BByte g, BByte b, BByte a)
{
	setColor(BColor(r, g, b, a));
}
void BTreeItem::setColor(const BColor& color)
{
	if (member.color != color)
	{
		member.color = color;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_ColorChanged, color);
	}
}
const BColor& BTreeItem::color() const
{
	return member.color;
}

void BTreeItem::setGraph(Graph graph)
{
	if (member.graph != graph)
	{
		member.graph = graph;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_GraphChanged, graph);
	}
}
Graph BTreeItem::graph() const
{
	return member.graph;
}

void BTreeItem::setImage(BImage* image)
{
	if (member.image != image)
	{
		member.image = image;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_ImageChanged, image);
	}
}
BImage* BTreeItem::image() const
{
	return member.image;
}

void BTreeItem::setIcon(BIcon* icon)
{
	if (member.icon != icon)
	{
		member.icon = icon;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_IconChanged, icon);
	}
}
BIcon* BTreeItem::icon()
{
	return member.icon;
}
const BIcon* BTreeItem::icon() const
{
	return member.icon;
}

bool BTreeItem::setWidget(BWidget* widget)
{
	if (member.widget != widget)
	{
		if (member.tree && member.widget)
		{
			member.tree->removeChild(member.widget);
			member.widget = 0;
		}
		member.widget = widget;
		if (member.tree && member.widget)
		{
			member.tree->addChild(member.widget);
			member.widget->setFloating(false);
		}
		member.dirtyTree();
		return true;
	}
	return false;
}
const BWidget* BTreeItem::widget() const
{
	return member.widget;
}
BWidget* BTreeItem::widget()
{
	return member.widget;
}

void BTreeItem::setFont(BFont* font)
{
	if (member.localFont != font)
	{
		member.localFont = font;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_FontChanged, font);
	}
}
const BFont* BTreeItem::font() const
{
	if (member.localFont)
		return member.localFont;
	if (member.tree)
		return member.tree->realFont();
	return 0;
}

void BTreeItem::setText(const BString& text)
{
	if (member.text != text)
	{
		member.text = text;
		member.dirtyTree();
		object_member(this)->check_emit(Signal_TextChanged, text);
	}
}
const BString& BTreeItem::text() const
{
	return member.text;
}

void BTreeItem::setTips(const BString& tips)
{
	if (member.tips != tips)
	{
		member.tips = tips;
		object_member(this)->check_emit(Signal_TipsChanged, tips);
	}
}
const BString& BTreeItem::tips() const
{
	return member.tips;
}

bool BTreeItem::setIconSize(int iconWidth, int iconHeight)
{
	return setIconSize(BSize(iconWidth, iconHeight));
}
bool BTreeItem::setIconSize(const BSize& iconSize)
{
	if (member.iconSize != iconSize)
	{
		member.iconSize = iconSize;
		member.dirty = true;
		member.dirtyTree();
		return true;
	}
	return false;
}
const BSize& BTreeItem::iconSize() const
{
	return member.ia_iconSize;
}

void BTreeItem::setTextFormat(BTextFormat* textFormat)
{
	if (member.block.format() != textFormat)
	{
		member.block.setFormat(textFormat);
		member.dirtyTree();
		this->emit(Signal_FormatChanged, textFormat);
	}
}
const BTextFormat* BTreeItem::textFormat() const
{
	return member.block.format();
}
BTextFormat* BTreeItem::textFormat()
{
	return member.block.format();
}

void BTreeItem::setBackground(BByte r, BByte g, BByte b, BByte a)
{
	setBackground(BColor(r, g, b, a));
}
void BTreeItem::setBackground(const BColor& background)
{
	if (member.background != background)
	{
		member.background = background;
		if (member.tree)
			member.tree->fresh();
	}
}
const BColor& BTreeItem::background() const
{
	return member.background;
}

void BTreeItem::setForeground(BByte r, BByte g, BByte b, BByte a)
{
	setForeground(BColor(r, g, b, a));
}
void BTreeItem::setForeground(const BColor& foreground)
{
	if (member.foreground != foreground)
	{
		member.foreground = foreground;
		if (member.tree)
			member.tree->fresh();
	}
}
const BColor& BTreeItem::foreground() const
{
	return member.foreground;
}

void BTreeItem::setRadius(const BSize& radius, PartFlag part)
{
	bool changed = false;
	if (member.round.empty())
	{
		member.round = new IRound();
		changed = true;
	}
	if (part & Part_Left && part & Part_Top)
	{
		if (member.round->radiusLeftTop != radius)
		{
			member.round->radiusLeftTop = radius;
			changed = true;
		}
	}
	if (part & Part_Left && part & Part_Bottom)
	{
		if (member.round->radiusLeftBottom != radius)
		{
			member.round->radiusLeftBottom = radius;
			changed = true;
		}
	}
	if (part & Part_Right && part & Part_Top)
	{
		if (member.round->radiusRightTop != radius)
		{
			member.round->radiusRightTop = radius;
			changed = true;
		}
	}
	if (part & Part_Right && part & Part_Bottom)
	{
		if (member.round->radiusRightBottom != radius)
		{
			member.round->radiusRightBottom = radius;
			changed = true;
		}
	}
	if (changed)
	{
		this->fresh();
	}
}
void BTreeItem::setRadius(const BSize& leftTop, const BSize& rightTop, const BSize& rightBottom, const BSize& leftBottom)
{
	if (member.round.empty() && leftTop.empty() && rightTop.empty() && rightBottom.empty() && leftBottom.empty())
		return;
	bool changed = false;
	if (member.round.empty())
	{
		member.round = new IRound();
		changed = true;
	}
	if (member.round->radiusLeftTop != leftTop)
	{
		member.round->radiusLeftTop = leftTop;
		changed = true;
	}
	if (member.round->radiusRightTop != rightTop)
	{
		member.round->radiusRightTop = rightTop;
		changed = true;
	}
	if (member.round->radiusRightBottom != rightBottom)
	{
		member.round->radiusRightBottom = rightBottom;
		changed = true;
	}
	if (member.round->radiusLeftBottom != leftBottom)
	{
		member.round->radiusLeftBottom = leftBottom;
		changed = true;
	}
	if (changed)
	{
		this->fresh();
	}
}
BSize BTreeItem::radius(PartFlag part)
{
	if (member.round)
	{
		if (part == Part_LeftTop)
			return member.round->radiusLeftTop;
		if (part == Part_RightTop)
			return member.round->radiusRightTop;
		if (part == Part_RightBottom)
			return member.round->radiusRightBottom;
		if (part == Part_LeftBottom)
			return member.round->radiusLeftBottom;
		return member.round->radiusLeftTop;
	}
	return BSize();
}

bool BTreeItem::hovered() const
{
	if (BTreeWidget* tree = member.tree)
	{
		return tree_member(tree)->hoveredItem == this;
	}
	return false;
}
bool BTreeItem::fresh() const
{
	if (BTreeWidget* tree = member.tree)
	{
		tree_member(tree)->dirty = true;
		tree->fresh();
		return true;
	}
	return false;
}

void BTreeItem::setParent(BTreeItem* parent)
{
	if (member.parent != parent)
	{
		BHolder<BTreeItem> holder;
		if (member.parent)
		{
			member.dirtyTree();
			holder = this;
			member.parent->removeChild(this);
		}
		if (parent)
		{
			parent->addChild(this);
			holder = 0;
			member.dirtyTree();
		}
	}
}
BTreeItem* BTreeItem::parent()
{
	return member.parent;
}
const BTreeItem* BTreeItem::parent() const
{
	return member.parent;
}

bool BTreeItem::addChild(BTreeItem* child)
{
	if (!child)
		return false;
	if (child == this)
		return false;
	if (member.children.contain(child))
		return true;
	member.children.append(child);
	if (item_member(child)->tree)
		item_member(child)->tree->removeItem(child);
	if (item_member(child)->parent)
		item_member(child)->parent->removeChild(child);
	item_member(child)->parent = this;
	item_member(child)->attach(member.tree);
	object_member(child)->emit(Signal_ParentChanged, BValue(this, true));
	member.raiseSignal(Signal_ItemInserted, child);
	member.dirtyTree();
	return true;
}
BTreeItem* BTreeItem::addChild(const BString& text)
{
	BTreeItem* item = new BTreeItem(text);
	this->addChild(item);
	return item;
}
BTreeItem* BTreeItem::addChild(Graph graph, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(graph, text, form);
	this->addChild(item);
	return item;
}
BTreeItem* BTreeItem::addChild(BIcon* icon, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(icon, text, form);
	this->addChild(item);
	return item;
}
BTreeItem* BTreeItem::addChild(BImage* image, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(image, text, form);
	this->addChild(item);
	return item;
}
BTreeItem* BTreeItem::addChild(BWidget* widget, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(widget, text, form);
	this->addChild(item);
	return item;
}

bool BTreeItem::insertChild(int pos, BTreeItem* child)
{
	if (!child)
		return false;
	if (child == this)
		return false;
	int index = member.children.find(child);
	if (index < member.children.size())
	{
		if (!member.children.move(index, pos))
			return false;
	}
	else
	{
		if (!member.children.insert(pos, child))
			return false;
		if (item_member(child)->tree)
			item_member(child)->tree->removeItem(child);
		if (item_member(child)->parent)
			item_member(child)->parent->removeChild(child);
		item_member(child)->parent = this;
		item_member(child)->attach(member.tree);
	}
	object_member(child)->emit(Signal_ParentChanged, BValue(this, true));
	member.raiseSignal(Signal_ItemInserted, child);
	member.dirtyTree();
	return true;
}
BTreeItem* BTreeItem::insertChild(int pos, const BString& text)
{
	BTreeItem* item = new BTreeItem(text);
	this->insertChild(pos, item);
	return item;
}
BTreeItem* BTreeItem::insertChild(int pos, Graph graph, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(graph, text, form);
	this->insertChild(pos, item);
	return item;
}
BTreeItem* BTreeItem::insertChild(int pos, BIcon* icon, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(icon, text, form);
	this->insertChild(pos, item);
	return item;
}
BTreeItem* BTreeItem::insertChild(int pos, BImage* image, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(image, text, form);
	this->insertChild(pos, item);
	return item;
}
BTreeItem* BTreeItem::insertChild(int pos, BWidget* widget, const BString& text, Form form)
{
	BTreeItem* item = new BTreeItem(widget, text, form);
	this->insertChild(pos, item);
	return item;
}

bool BTreeItem::removeChild(int index)
{
	BTreeItem* child = this->child(index);
	return removeChild(child);
}
bool BTreeItem::removeChild(BTreeItem* child)
{
	if (!child)
		return false;
	if (child == this)
		return false;
	if (!member.children.contain(child))
		return false;
	BHolder<BTreeItem> holder(child);
	item_member(child)->parent = 0;
	item_member(child)->detach(member.tree);
	member.children.remove(child);
	object_member(child)->emit(Signal_ParentChanged);
	member.raiseSignal(Signal_ItemRemoved, child);
	member.dirtyTree();
	return true;
}
bool BTreeItem::removeChild(const BString& text)
{
	BTreeItem* child = this->child(text);
	return removeChild(child);
}

bool BTreeItem::replaceChild(BTreeItem* child, BTreeItem* item)
{
	if (!child)
		return false;
	if (item_member(child)->parent != this)
		return false;
	if (member.tree)
	{
		item_member(child)->selected = false;
		tree_member(member.tree)->selectedItems.remove(child);
		object_member(member.tree)->emit(Signal_ItemSelected, false);
	}

	BHolder<BTreeItem> holder(child);
	item_member(child)->detach(member.tree);
	if (item)
	{
		int index = member.children.find(child);
		member.children[index] = item;
		if (item_member(item)->tree && item_member(item)->tree != member.tree)
			item_member(item)->tree->removeItem(item);
		if (item_member(item)->parent)
			item_member(item)->parent->removeChild(item);
		item_member(item)->parent = this;
		item_member(item)->attach(member.tree);
		member.raiseSignal(Signal_ItemRemoved, child);
		member.raiseSignal(Signal_ItemInserted, item);
	}
	else
	{
		member.children.remove(item);
		member.raiseSignal(Signal_ItemRemoved, child);
	}

	member.dirtyTree();
	this->fresh();
	return true;
}

void BTreeItem::clearChildren()
{
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		item_member(child)->parent = 0;
		item_member(child)->detach(member.tree);
	}
	member.children.clear();
	member.dirtyTree();
}

int BTreeItem::childCount() const
{
	return member.children.size();
}
BTreeItem* BTreeItem::child(int index)
{
	return member.children.at(index);
}
const BTreeItem* BTreeItem::child(int index) const
{
	return member.children.at(index);
}

BTreeItem* BTreeItem::child(const BString& text)
{
	for (int i = 0; i < member.children.size(); i++)
	{
		const BString& childText = member.children[i]->text();
		if (childText == text)
			return member.children[i];
	}
	return 0;
}
const BTreeItem* BTreeItem::child(const BString& text) const
{
	for (int i = 0; i < member.children.size(); i++)
	{
		if (member.children[i]->text() == text)
			return member.children[i];
	}
	return 0;
}

BTreeItem* BTreeItem::childOfName(const BString& name)
{
	for (int i = 0; i < member.children.size(); i++)
	{
		if (member.children[i]->name() == name)
			return member.children[i];
	}
	return 0;
}
const BTreeItem* BTreeItem::childOfName(const BString& name) const
{
	for (int i = 0; i < member.children.size(); i++)
	{
		if (member.children[i]->name() == name)
			return member.children[i];
	}
	return 0;
}

BTreeItem* BTreeItem::childOfAsset(const BValue& asset)
{
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		if (child->asset() == asset)
			return child;
	}
	return 0;
}
const BTreeItem* BTreeItem::childOfAsset(const BValue& asset) const
{
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		if (child->asset() == asset)
			return child;
	}
	return 0;
}

BTreeItem* BTreeItem::findByText(const BString& text)
{
	if (member.text == text)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		BTreeItem* item = child->findByText(text);
		if (item)
			return item;
	}
	return 0;
}
const BTreeItem* BTreeItem::findByText(const BString& text) const
{
	if (member.text == text)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		const BTreeItem* child = member.children[i];
		const BTreeItem* item = child->findByText(text);
		if (item)
			return item;
	}
	return 0;
}

BTreeItem* BTreeItem::findByAsset(const BValue& asset)
{
	if (asset.empty())
		return 0;
	if (this->asset() == asset)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		BTreeItem* child = member.children[i];
		BTreeItem* item = child->findByAsset(asset);
		if (item)
			return item;
	}
	return 0;
}
const BTreeItem* BTreeItem::findByAsset(const BValue& asset) const
{
	if (asset.empty())
		return 0;
	if (this->asset() == asset)
		return this;
	for (int i = 0; i < member.children.size(); i++)
	{
		const BTreeItem* child = member.children[i];
		const BTreeItem* item = child->findByAsset(asset);
		if (item)
			return item;
	}
	return 0;
}

BTreeItem* BTreeItem::create(const BString& path)
{
	int end = path.find('/');
	if (end == path.size())
	{
		BTreeItem* item = this->child(path);
		if (item == 0)
			item = this->addChild(path);
		return item;
	}
	BString text;
	path.substr(text, 0, end);
	BTreeItem* item = this->child(text);
	if (item == 0)
	{
		item = this->addChild(text);
	}
	int pos = end + 1;
	while (item && pos < path.size())
	{
		end = path.find('/', pos);
		path.substr(text, pos, end);
		BTreeItem* child = item->child(text);
		if (child == 0)
			child = item->addChild(text);
		item = child;
		pos = end + 1;
	}
	return item;
}

BTreeItem* BTreeItem::locate(const BString& path)
{
	if (path.empty())
		return this;
	BStringArray textlst = path.split('/');
	BTreeItem* node = this->child(textlst.first());
	textlst.remove(0);
	while (node && textlst.size())
	{
		const BString& text = textlst.first();
		node = node->child(text);
		textlst.remove(0);
	}
	return node;
}
const BTreeItem* BTreeItem::locate(const BString& path) const
{
	if (path.empty())
		return this;
	BStringArray textlst = path.split('/');
	const BTreeItem* node = this->child(textlst.first());
	textlst.remove(0);
	while (node && textlst.size())
	{
		const BString& text = textlst.first();
		node = node->child(text);
		textlst.remove(0);
	}
	return node;
}

BTreeWidget* BTreeItem::treeWidget()
{
	return member.tree;
}
const BTreeWidget* BTreeItem::treeWidget() const
{
	return member.tree;
}

BTreeItem* BTreeItem::root()
{
	BTreeItem* item = this;
	while (item_member(item)->parent)
		item = item_member(item)->parent;
	return item;
}
const BTreeItem* BTreeItem::root() const
{
	const BTreeItem* item = this;
	while (item_member(item)->parent)
		item = item_member(item)->parent;
	return item;
}

BTreeItem* BTreeItem::prev()
{
	if (member.tree)
	{
		int index = this->index();
		if (member.parent)
		{
			return member.parent->child(index - 1);
		}
		return member.tree->item(index - 1);
	}
	return 0;
}
const BTreeItem* BTreeItem::prev() const
{
	if (member.tree)
	{
		int index = this->index();
		if (member.parent)
		{
			return member.parent->child(index - 1);
		}
		return member.tree->item(index - 1);
	}
	return 0;
}

BTreeItem* BTreeItem::next()
{
	if (member.tree)
	{
		int index = this->index();
		if (member.parent)
		{
			return member.parent->child(index + 1);
		}
		return member.tree->item(index + 1);
	}
	return 0;
}
const BTreeItem* BTreeItem::next() const
{
	if (member.tree)
	{
		int index = this->index();
		if (member.parent)
		{
			return member.parent->child(index + 1);
		}
		return member.tree->item(index + 1);
	}
	return 0;
}

bool BTreeItem::above(const BTreeItem* item) const
{
	if (!item)
		return false;
	BTreeItem* parent = item_member(item)->parent;
	while (parent)
	{
		if (parent == this)
			return true;
		parent = item_member(parent)->parent;
	}
	return false;
}
bool BTreeItem::under(const BTreeItem* item) const
{
	BTreeItem* parent = member.parent;
	while (parent)
	{
		if (parent == item)
			return true;
		parent = item_member(parent)->parent;
	}
	return false;
}
bool BTreeItem::contain(const BTreeItem* item) const
{
	if (!item)
		return false;
	for (int i = 0; i < member.children.size(); i++)
	{
		if (member.children[i] == item)
			return true;
	}
	return false;
}

bool BTreeItem::setIndex(int index)
{
	if (member.parent)
	{
		BTreeItemHolderArray& children = item_member(member.parent)->children;
		int pos = children.find(this);
		if (children.move(pos, index))
		{
			member.raiseSignal(Signal_OrderChanged);
			this->fresh();
			return true;
		}
	}
	else
	{
		BTreeItemHolderArray& items = tree_member(member.tree)->items;
		int pos = items.find(this);
		if (items.move(pos, index))
		{
			member.raiseSignal(Signal_OrderChanged);
			this->fresh();
			return true;
		}
	}
	return false;
}
int BTreeItem::index() const
{
	if (BTreeItem* parent = member.parent)
	{
		BArray<BTreeItemHolder>& children = item_member(parent)->children;
		return children.find(this);
	}
	if (member.tree)
	{
		return member.tree->itemIndex(this);
	}
	return -1;
}
int BTreeItem::level() const
{
	int level = 0;
	const BTreeItem* item = this->parent();
	while (item)
	{
		level++;
		item = item_member(item)->parent;
	}
	return level;
}

bool BTreeItem::raise()
{
	if (member.parent)
	{
		BTreeItemHolderArray& children = item_member(member.parent)->children;
		int pos = children.find(this);
		if (children.swap(pos, children.size() - 1))
		{
			member.raiseSignal(Signal_OrderChanged);
			this->fresh();
			return true;
		}
	}
	if (member.tree)
	{
		BTreeItemHolderArray& items = tree_member(member.tree)->items;
		int pos = items.find(this);
		if (items.swap(pos, items.size() - 1))
		{
			member.raiseSignal(Signal_OrderChanged);
			this->fresh();
			return true;
		}
	}
	return false;
}
bool BTreeItem::lower()
{
	if (member.parent)
	{
		BTreeItemHolderArray& children = item_member(member.parent)->children;
		int pos = children.find(this);
		if (children.move(pos, 0))
		{
			member.raiseSignal(Signal_OrderChanged);
			this->fresh();
			return true;
		}
	}
	else
	{
		BTreeItemHolderArray& items = tree_member(member.tree)->items;
		int pos = items.find(this);
		if (items.move(pos, 0))
		{
			member.raiseSignal(Signal_OrderChanged);
			this->fresh();
			return true;
		}
	}
	return false;
}

BString BTreeItem::path(const char* split) const
{
	BString text = this->text();
	const BTreeItem* item = this->parent();
	while (item)
	{
		text.prepend(split);
		text.prepend(item->text());
		item = item->parent();
	}
	return text;
}
BString BTreeItem::path(const BString& split) const
{
	BString text = this->text();
	const BTreeItem* item = this->parent();
	while (item)
	{
		text.prepend(split);
		text.prepend(item->text());
		item = item->parent();
	}
	return text;
}

BString BTreeItem::pathTo(const BTreeItem* parent, const char* split) const
{
	if (this == parent)
		return BString();
	if (parent && !this->under(parent))
		return BString();
	BString text = this->text();
	const BTreeItem* item = this->parent();
	while (item && item != parent)
	{
		text.prepend(split);
		text.prepend(item->text());
		item = item->parent();
	}
	return text;
}
BString BTreeItem::pathTo(const BTreeItem* parent, const BString& split) const
{
	if (this == parent)
		return BString();
	if (parent && !this->under(parent))
		return BString();
	BString text = this->text();
	const BTreeItem* item = this->parent();
	while (item && item != parent)
	{
		text.prepend(split);
		text.prepend(item->text());
		item = item->parent();
	}
	return text;
}

BRect BTreeItem::area() const
{
	BRect rect = member.area;
	if (member.tree)
	{
		const BRect& area = member.tree->area();
		rect += area.pos();
		rect.left() = area.left();
		rect.right() = area.right();
	}
	return rect;
}
BRect BTreeItem::rect() const
{
	BRect rect = member.rect();
	if (member.tree)
	{
		rect += member.tree->offset();
	}
	return rect;
}
BRect BTreeItem::iconRect() const
{
	BRect rect =  member.ia_iconRect + member.pos;
	if (member.tree)
	{
		rect += member.tree->offset();
	}
	return rect;
}
BRect BTreeItem::textRect() const
{
	BRect rect = member.ia_textRect + member.pos;
	if (member.tree)
	{
		rect += member.tree->offset();
	}
	return rect;
}
BRect BTreeItem::textArea() const
{
	BRect rect = member.ia_textArea + member.pos;
	if (member.tree)
	{
		rect += member.tree->offset();
	}
	return rect;
}
BRect BTreeItem::arrowArea() const
{
	BRect rect = member.arrowArea;
	if (member.tree)
	{
		rect += member.tree->offset();
	}
	return rect;
}
BRect BTreeItem::arrowRect() const
{
	BRect rect = member.arrowRect;
	if (member.tree)
	{
		rect += member.tree->offset();
	}
	return rect;
}
